<?php

declare(strict_types=1);

namespace Tool\Command;

use Marx\Console\Color;
use Marx\Console\Command\AbstractCommand;

/**
 * 时间工具.
 */
class DateCommand extends AbstractCommand
{
    public function __construct()
    {
        $this->setName('date');
        $this->setDesc('php date tool');
        $this->addOption('week', 'w', false, 'show week start time and end time,eg:-w -d 1970-01-01');
        $this->addOption('month', 'm', false, 'show month start time and end time,eg:-m -d 1970-01-01');
        $this->addOption('usage', 'u', false, 'show strtotime usage');
        $this->addOption('date', 'd', false, 'date argument');
    }

    public function execute(): void
    {
        if (!is_null($this->input->getOption('week'))) {
            $this->week();

            return;
        }

        if (!is_null($this->input->getOption('month'))) {
            $this->month();

            return;
        }

        if (!is_null($this->input->getOption('usage'))) {
            $this->usage();

            return;
        }

        $this->to();
    }

    private function to(): void
    {
        while (true) {
            $this->output->askQuestion(Color::yellow('input date or time,or empty string to exit'));
            $input = $this->input->readAnswer();
            if ('' === $input) {
                $this->output->write('bye!');

                break;
            }

            if ($this->isTimestamp($input)) {
                $input = str_replace(',', '', $input);
                $this->output->write(Color::green($input.','.date('Y-m-d H:i:s', intval($input))));
            } else {
                if (strpos($input, ',') > 0) {
                    list($input, $time) = explode(',', $input, 2);
                    if (!$this->isTimestamp($time)) {
                        $time = strtotime($time);
                    } else {
                        $time = str_replace(',', '', $time);
                    }
                } else {
                    $time = time();
                }

                $time = strtotime($input, intval($time));
                $this->output->write(Color::green($time.','.date('Y-m-d H:i:s', $time)));
            }
        }
    }

    private function week(): void
    {
        $date = $this->input->getOption('date') ?: date('YmdHis');
        $time = strtotime($date);
        $this->output->write('week start time:'.Color::green((string) strtotime('-1 week monday 00:00:00', $time)));
        $this->output->write('week end time:'.Color::green((string) strtotime('sunday 23:59:59', $time)));
    }

    private function month(): void
    {
        $date = $this->input->getOption('date') ?: date('YmdHis');
        $time = strtotime($date);
        $this->output->write('month start time:'.Color::green((string) strtotime('first day of this month 00:00:00', $time)));
        $this->output->write('month end time:'.Color::green((string) strtotime('last day of this month 23:59:59', $time)));
    }

    private function usage(): void
    {
        $eg = [
            'strtotime("monday last week 00:00:00"):'.Color::grey((string) strtotime('monday last week 00:00:00')),
            'strtotime("sunday last week 23:59:59"):'.Color::grey((string) strtotime('sunday last week 23:59:59')),
            'strtotime("monday next week 00:00:00"):'.Color::grey((string) strtotime('monday next week 00:00:00')),
            'strtotime("sunday next week 23:59:59"):'.Color::grey((string) strtotime('sunday next week 23:59:59')),
            'strtotime("first day of last month 00:00:00"):'.Color::grey((string) strtotime('first day of last month 00:00:00')),
            'strtotime("last day of last month 23:59:59"):'.Color::grey((string) strtotime('last day of last month 23:59:59')),
            'strtotime("first day of next month 00:00:00"):'.Color::grey((string) strtotime('first day of next month 00:00:00')),
            'strtotime("last day of next month 23:59:59"):'.Color::grey((string) strtotime('last day of next month 23:59:59')),
        ];
        $this->output->writeLn(...$eg);
    }

    private function isTimestamp(string $str): bool
    {
        return (bool) (preg_match('/^\d+$/', $str) || preg_match('/^\d+(,\d{3})*$/', $str));
    }
}
